﻿using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using my_proxy.Utils;

namespace my_proxy.RequestHandlers
{
    public class AnonymousRequestHandler : OpenRequestHandler
    {
          
        //bla vla
        public AnonymousRequestHandler(Configuration cf, HttpListenerContext context, FileReader fr,object fileLock)
            : base(cf, context, fr, fileLock){}

        protected override HttpWebRequest GetRequest()
        {
            if (this.Context.Request.HttpMethod == "GET")
            {
                if (this.RemoteUrl.Contains("?"))
                {
                    string conURL = this.RemoteUrl.Substring(0, this.RemoteUrl.IndexOf('?'));
                    string param = this.RemoteUrl.Substring(this.RemoteUrl.IndexOf('?') + 1);
                    param = replaceOccureOfWord(new StringBuilder(param)).ToString();
                    this.RemoteUrl = conURL + "?" + param;
                }
            }
            // Create a request to the server
            HttpWebRequest requestToServer = (HttpWebRequest)WebRequest.Create(this.RemoteUrl);

            // Set some options
            requestToServer.Method = this.Context.Request.HttpMethod;
            requestToServer.UserAgent = this.Context.Request.UserAgent;
            requestToServer.KeepAlive = requestToServer.KeepAlive;
            requestToServer.Proxy = null;

            // For POST, write the post data extracted from the incoming request
            if (requestToServer.Method == "POST")
            {
                const int bufferSize = 1024;
                Stream clientStream = this.Context.Request.InputStream;
                byte[] clientPostData = new byte[bufferSize];
                requestToServer.ContentType = this.Context.Request.ContentType;
                int read = clientStream.Read(clientPostData, 0, bufferSize);
                StringBuilder data = new StringBuilder();
                Stream stream = requestToServer.GetRequestStream();
                int mRead = 0;
                //read data untile the end of the stream and write it to the rquest sended
                while (read > 0)
                {
                    StringBuilder tempString = new StringBuilder(Encoding.UTF8.GetString(clientPostData, 0, clientPostData.Length));
                    data.Append(tempString);
                    read = clientStream.Read(clientPostData, 0, bufferSize);
                }
                // replacing entire data at once
                data = replaceOccureOfWord(data);
                mRead = data.Length;
                byte[] clientPostData2 = new byte[mRead];
                System.Text.Encoding encoding = System.Text.Encoding.UTF8;
                clientPostData2 = encoding.GetBytes(data.ToString());
                while (mRead > 0)
                {
                    stream.Write(clientPostData2, 0, mRead);
                    mRead = clientStream.Read(clientPostData, 0, bufferSize);
                }
                stream.Close();

                //TODO: check for mails in the request (use data)
                if (checkForMail(data))
                {
                    ProxyListener.forbbiden(Context);
                }
            }

            //check for mails in the request headers
            for (int i = 0; i < requestToServer.Headers.Count; i++)
            {
                StringBuilder m_header = new StringBuilder(requestToServer.Headers[i]);
                if (checkForMail(m_header))
                {    // checks for Mails in the headers
                    ProxyListener.forbbiden(Context);
                }

                // the Header replacement
                if (!WebHeaderCollection.IsRestricted(requestToServer.Headers.AllKeys[i].ToString())) //SafeHeaders.Contains(requestToServer.Headers.AllKeys[i].ToString()))
                    requestToServer.Headers.Set(requestToServer.Headers.AllKeys[i].ToString(), replaceOccureOfWord(m_header).ToString());
            }
            return requestToServer;
        }
    }
}
